package com.sws.hmclient.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sws.hmclient.entity.*;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OSProcess;
import oshi.software.os.OperatingSystem;
import oshi.util.FormatUtil;
import oshi.util.Util;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class SystemInfoUtils {

    private static SystemInfo systemInfo = new SystemInfo();
    private static HardwareAbstractionLayer hardware = systemInfo.getHardware();
    private static OperatingSystem operatingSystem = systemInfo.getOperatingSystem();

    public Sysinfo getSysInfo() throws UnknownHostException, ParseException {

        Sysinfo sysinfo = new Sysinfo();
        Properties props = System.getProperties();
        //操作系统名
        sysinfo.setOsname(props.getProperty("os.name"));
        //系统架构
        sysinfo.setOsarch(props.getProperty("os.arch"));
        //服务器名称
        sysinfo.setComputername(InetAddress.getLocalHost().getHostName());
        //服务器Ip
        sysinfo.setComputerip(InetAddress.getLocalHost().getHostAddress());
        //项目路径
        sysinfo.setUserdir(props.getProperty("user.dir"));
        // {"computerIp":"192.168.32.1","computerName":"SD-20200724VSMS","osArch":"amd64","userDir":"D:\\elAdmin\\SWS\\HMServer","osName":"Windows 10"}
        return sysinfo;
    }


    public  Cpuinfo getCpuInfo() {
        Cpuinfo cpuInfo = new Cpuinfo();
        SystemInfo systemInfo = new SystemInfo();
        HardwareAbstractionLayer hardware = systemInfo.getHardware();
        CentralProcessor processor = hardware.getProcessor();
        // CPU信息
        long[] prevTicks = processor.getSystemCpuLoadTicks();

        long[] ticks = processor.getSystemCpuLoadTicks();
        long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
        long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
        long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
        long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
        long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
        long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
        long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
        long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
        long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
        //cpu个数
        cpuInfo.setCpunum(processor.getLogicalProcessorCount());
        //cpu系统使用率
        String Csys=new DecimalFormat("#.##").format((cSys * 1.0 / totalCpu) * 100);
        cpuInfo.setCsys(Csys);
        //cpu用户使用率
        String User= new DecimalFormat("#.##").format((user * 1.0 / totalCpu) * 100);
        cpuInfo.setUser(User);
        //cpu当前等待率
        String Iowait= new DecimalFormat("#.##").format((iowait * 1.0 / totalCpu) * 100);
        cpuInfo.setIowait(Iowait);
        //cpu当前使用率
        String Idle= new DecimalFormat("#.##").format((1.0 - (idle * 1.0 / totalCpu)) * 100);
        cpuInfo.setIdle(Idle);


        System.out.println();
        //{"cSys":"19.8%","idle":"33.35%","iowait":"0%","user":"13.55%","cpuNum":8}
        return cpuInfo;
    }

    /**
     * 系统内存信息
     */
    public  Meminfo getMemInfo() {
        Meminfo meminfo=new Meminfo();
        GlobalMemory memory = systemInfo.getHardware().getMemory();
        //总内存
        long totalByte = memory.getTotal();
        //剩余
        long acaliableByte = memory.getAvailable();
        //总内存
        meminfo.setTotal(formatByte(totalByte));
        //使用
        meminfo.setUsed(formatByte(totalByte - acaliableByte));
        //剩余内存
        meminfo.setFree(formatByte(acaliableByte));
        //使用率
       meminfo.setUsagerate(new DecimalFormat("#.##").format((totalByte - acaliableByte) * 1.0 / totalByte));
        return meminfo;
    }

    /**
     * 系统盘符信息
     */
    public List<Sysfileinfo>  getSysFileInfo() {

        List<Sysfileinfo> list =new ArrayList();
        OperatingSystem operatingSystem = systemInfo.getOperatingSystem();
        FileSystem fileSystem = operatingSystem.getFileSystem();
        OSFileStore[] fsArray = fileSystem.getFileStores();
        for (OSFileStore fs : fsArray) {
            Sysfileinfo fileinfo=new Sysfileinfo();
            //盘符路径
            fileinfo.setDirname(fs.getMount());
            //盘符类型
            fileinfo.setSystypename(fs.getType());
            //文件类型
            fileinfo.setTypename(fs.getName());
            //总大小
            fileinfo.setTotal(formatByte(fs.getTotalSpace()));
            //剩余大小
            fileinfo.setFree(formatByte(fs.getUsableSpace()));
            //已经使用量
            fileinfo.setUsed(formatByte(fs.getTotalSpace() - fs.getUsableSpace()));
            if (fs.getTotalSpace() == 0) {
                //资源的使用率
                fileinfo.setUsage("0");
            } else {                          //#.##%
                fileinfo.setUsage(new DecimalFormat("#.##").format((fs.getTotalSpace() - fs.getUsableSpace()) * 1.0 / fs.getTotalSpace()));
            }
            list.add(fileinfo);
        }
        return list;
    }



    /**
     * 获取全部进程信息
     */
    public  List<Processesinfo> getProcesses() throws UnknownHostException{
       List<Processesinfo> list=new ArrayList<>();
        GlobalMemory memory = systemInfo.getHardware().getMemory();
        List<OSProcess> procs = Arrays.asList(operatingSystem.getProcesses(operatingSystem.getProcessCount(), OperatingSystem.ProcessSort.CPU));
        System.out.println("   PID  %CPU %MEM       VSZ       RSS Name");
        for (int i = 0; i < procs.size() && i < operatingSystem.getProcessCount(); i++) {
            Processesinfo processeSinfo=new Processesinfo();
            OSProcess p = procs.get(i);
            processeSinfo.setPID(p.getProcessID());
            processeSinfo.setCPU(100d * (p.getKernelTime() + p.getUserTime()) / p.getUpTime());
            processeSinfo.setMEM(100d * p.getResidentSetSize() / memory.getTotal());
            processeSinfo.setVSZ(FormatUtil.formatBytes(p.getVirtualSize()));
            processeSinfo.setRSS(FormatUtil.formatBytes(p.getResidentSetSize()));
            processeSinfo.setName(p.getName());
            list.add(processeSinfo);
        }
        return  list;
    }

    /**
     * 获取单个进程信息
     */
    public  Processesinfo getProcesseByPod(int pid) throws UnknownHostException{
        GlobalMemory memory = systemInfo.getHardware().getMemory();
        OSProcess osp=operatingSystem.getProcess(pid);
        Processesinfo processeSinfo=new Processesinfo();
        processeSinfo.setCPU(100d * (osp.getKernelTime() + osp.getUserTime()) / osp.getUpTime());
        processeSinfo.setMEM(100d * osp.getResidentSetSize() / memory.getTotal());
        processeSinfo.setVSZ(FormatUtil.formatBytes(osp.getVirtualSize()));
        processeSinfo.setRSS(FormatUtil.formatBytes(osp.getResidentSetSize()));
        processeSinfo.setName(osp.getName());

        return  processeSinfo;
    }

    /**
     * 单位转换
     */
    private static String formatByte(long byteNumber) {
        //换算单位
        double FORMAT = 1024.0;
        double kbNumber = byteNumber / FORMAT;
        if (kbNumber < FORMAT) {
            return new DecimalFormat("#.##KB").format(kbNumber);
        }
        double mbNumber = kbNumber / FORMAT;
        if (mbNumber < FORMAT) {
            return new DecimalFormat("#.##MB").format(mbNumber);
        }
        double gbNumber = mbNumber / FORMAT;
        if (gbNumber < FORMAT) {          //GB#.##
            return new DecimalFormat("#.##").format(gbNumber);
        }
        double tbNumber = gbNumber / FORMAT;
        return new DecimalFormat("#.##TB").format(tbNumber);
    }

}
